package com.tbb.app.common.entity;

import com.tbb.app.common.exception.BaseErrorCode;
import com.tbb.app.common.exception.CommonCode;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import org.springframework.util.StringUtils;

import java.util.Objects;

/**
 * @author LiuSenLin
 * @date 2020/1/16 19:54
 */
@Accessors(chain = true)
@Data
@ApiModel(description = "统一响应结构")
public class BaseResponse<T> {

    @ApiModelProperty(value = "响应状态")
    private Boolean status = Boolean.TRUE;

    @ApiModelProperty(value = "响应描述信息")
    private String message = CommonCode.C00000.getMessage();

    @ApiModelProperty(value = "响应编码，00000-操作成功，00001-操作失败，00002-登录过期，00003-参数验证失败")
    private String code = CommonCode.C00000.getCode();

    @ApiModelProperty(value = "响应数据载荷")
    private T data;

    /**
     * 返回成功
     *
     * @return
     */
    public static <T> BaseResponse<T> ok() {
        return ok(null);
    }


    /**
     * 返回成功 并设置提示消息
     *
     * @param message
     * @return
     */
    public static <T> BaseResponse<T> ok(String message) {
        return ok(message, null);
    }

    /**
     * 返回成功并设置返回数据
     *
     * @param data
     * @param <T>
     * @return
     */
    public static <T> BaseResponse<T> data(T data) {
        return ok(null, data);
    }

    /**
     * 返回成功并设置消息和返回数据
     *
     * @param message
     * @param data
     * @param <T>
     * @return
     */
    public static <T> BaseResponse<T> ok(String message, T data) {
        BaseResponse<T> instance = instance(CommonCode.C00000, data);
        if (!StringUtils.isEmpty(message)) {
            instance.setMessage(message);
        }
        return instance;
    }

    /**
     * 返回失败
     *
     * @param <T>
     * @return
     */
    public static <T> BaseResponse<T> failed() {
        return failed(null);
    }

    /**
     * 返回失败并设置消息
     *
     * @param message
     * @param <T>
     * @return
     */
    public static <T> BaseResponse<T> failed(String message) {
        return failed(null, message);
    }

    /**
     * 返回失败并设置错误码和消息
     *
     * @param code
     * @param message
     * @param <T>
     * @return
     */
    public static <T> BaseResponse<T> failed(String code, String message) {
        BaseResponse<T> response = instance(CommonCode.C00001, null);
        if (!StringUtils.isEmpty(code)) {
            response.setCode(code);
        }
        if (!StringUtils.isEmpty(message)) {
            response.setMessage(message);
        }
        response.setStatus(false);
        return response;
    }

    /**
     * 通过错误码和返回数据创建一个响应对象
     *
     * @param codeObject 错误码对象
     * @param data       返回data
     * @param <T>        泛型
     * @return
     */
    public static <T> BaseResponse<T> instance(BaseErrorCode codeObject, T data) {
        Objects.requireNonNull(codeObject, "parameter [codeObject] can not be null!");
        BaseResponse<T> response = new BaseResponse<>();
        response.setStatus(codeObject.getCode().endsWith(CommonCode.C00000.getCode()));
        response.setMessage(codeObject.getMessage());
        response.setCode(codeObject.getCode());
        response.setData(data);
        return response;
    }

    public static <T> BaseResponse<T> instance(BaseErrorCode codeObject) {
        return instance(codeObject, null);
    }
}
